package com.ly.heart.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ly.common.core.domain.AjaxResult;
import com.ly.common.core.domain.entity.SysDept;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.StringUtils;
import com.ly.common.utils.erp.ConstUtil;
import com.ly.common.utils.erp.ReturnPage;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.heart.domain.ActTaskCommentEntity;
import com.ly.heart.domain.KingPurchaseApplyMaterialEntity;
import com.ly.heart.domain.dto.KingPurchaseApplyQueryDto;
import com.ly.heart.domain.dto.StartProcessDto;
import com.ly.common.core.domain.ActCurrentTaskVo;
import com.ly.heart.domain.vo.KingPurchaseApplyVo;
import com.ly.heart.mapper.KingPurchaseApplyMapper;
import com.ly.heart.service.IActModelService;
import com.ly.heart.service.IActTaskCommentService;
import com.ly.heart.service.IKingPurchaseApplyMaterialService;
import com.ly.heart.service.IKingPurchaseApplyService;
import com.ly.heart.util.ChineseToPinyin;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.system.service.ISysDeptService;
import org.springframework.stereotype.Service;
import com.ly.heart.domain.KingPurchaseApplyEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 金蝶-采购申请单Service业务层处理
 *
 * @author cxl
 * @date 2024-08-31
 */
@Service
public class KingPurchaseApplyServiceImpl extends ServiceImpl<KingPurchaseApplyMapper,KingPurchaseApplyEntity> implements IKingPurchaseApplyService {

    @Resource
    private KingPurchaseApplyMapper kingPurchaseApplyMapper;
    @Resource
    private ISysDeptService deptService;
    @Resource
    private IKingPurchaseApplyMaterialService purchaseApplyMaterialService;
    @Resource
    private IActModelService actModelService;
    @Resource
    private IActTaskCommentService actTaskCommentService;

    @Override
    public AjaxResult getKingPurchaseApplyPageList(KingPurchaseApplyQueryDto queryDto) {
        List<KingPurchaseApplyVo> list = purchaseApplyMaterialService.getPurchaseApplyList(queryDto);
        list.forEach(purchaseApplyVo -> {
            ActTaskCommentEntity actTaskCommentEntity = actTaskCommentService.queryLastComment(purchaseApplyVo.getInstanceId());
            if ( actTaskCommentEntity != null ) {
                purchaseApplyVo.setApprovedUser ( actTaskCommentEntity.getApprovedUser () );
                purchaseApplyVo.setRemark ( actTaskCommentEntity.getRemark () );
            }
            ActCurrentTaskVo currentTaskVo = actModelService.getCurrentTaskByInstanceId(purchaseApplyVo.getInstanceId());
            Optional.ofNullable(currentTaskVo).ifPresent(purchaseApplyVo::setCurrentTask);
        });
        Page<KingPurchaseApplyVo> page = new Page<>(queryDto.getPage(), queryDto.getLimit());
        return AjaxResult.success ( ReturnPage.getReturnPage ( page, list ) );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult draft(KingPurchaseApplyEntity kingPurchaseApply){
        if(StringUtils.isEmpty(kingPurchaseApply.getId())){
            String purchaseApplyId = SnowflakeIdWorker.getInstance().nextStringId();
            Date nowDate = DateUtils.getNowDate();
            String userId = SecurityUtils.getLoginUser().getUser().getUserId();
            kingPurchaseApply.setId(purchaseApplyId).setCreateTime(nowDate).setCreateName(userId);
            if(StringUtils.isEmpty(kingPurchaseApply.getDocCode())){
                String companyId = CurrentUserUtil.getCompanyId();
                SysDept sysDept = deptService.getById(companyId);
                int count = this.count();
                String countStr = String.format("%06d", count);
                String firstLetter = ChineseToPinyin.getFirstLetter(sysDept.getDeptName());
                String docCode = firstLetter.concat("_CGSQ_").concat(countStr);
                kingPurchaseApply.setDocCode(docCode);
            }
            if(!CollectionUtils.isEmpty(kingPurchaseApply.getMaterialLists())){
                saveMaterialAndDetail(kingPurchaseApply);
            }
            //流程状态：暂存
            kingPurchaseApply.setState(ConstUtil.STATE_IN_DRAFT);
            boolean save = this.save(kingPurchaseApply);
            if(save){
                return AjaxResult.success("暂存采购申请单成功！",kingPurchaseApply.getId());
            }
            return AjaxResult.error("暂存采购申请单失败！");
        }else{
            return update(kingPurchaseApply);
        }
    }

    @Override
    public AjaxResult submit(KingPurchaseApplyEntity kingPurchaseApply) {
        if ( StringUtils.isBlank ( kingPurchaseApply.getId () ) ) {
            return AjaxResult.error ("请先暂存该单据！");
        }
        if(Objects.isNull(kingPurchaseApply.getModelId())){
            return AjaxResult.error("审批流程modelId不能为空！");
        }
        if (CollectionUtils.isEmpty(kingPurchaseApply.getMaterialLists())) {
            return AjaxResult.error("物料信息不能为空！");
        }
        purchaseApplyMaterialService.remove(new LambdaQueryWrapper<KingPurchaseApplyMaterialEntity>().eq(KingPurchaseApplyMaterialEntity::getPurchaseApplyId,kingPurchaseApply.getId()));
        //保存物料明细
        saveMaterialAndDetail(kingPurchaseApply);
        //启动审批流程
        StartProcessDto startDto = new StartProcessDto().setBusinessId(kingPurchaseApply.getId()).setBusinessType(kingPurchaseApply.getBusinessType()).setModelId(kingPurchaseApply.getModelId());
        startDto.setBusinessName("采购申请单_".concat(kingPurchaseApply.getDocCode()));
        String instanceId = actModelService.startProcess(startDto);
        kingPurchaseApply.setState(ConstUtil.STATE_IN_PROCESS).setInstanceId(instanceId);
        boolean updated = this.updateById(kingPurchaseApply);
        if ( !updated ) {
            return AjaxResult.error( "提交采购申请单失败！!" );
        }
        return AjaxResult.success ( "提交采购申请单成功!" );
    }

    @Override
    public AjaxResult update(KingPurchaseApplyEntity kingPurchaseApply) {
        if(StringUtils.isEmpty(kingPurchaseApply.getId())){
            return AjaxResult.error("采购申请单id不能为空！");
        }
        purchaseApplyMaterialService.remove(new LambdaQueryWrapper<KingPurchaseApplyMaterialEntity>().eq(KingPurchaseApplyMaterialEntity::getPurchaseApplyId,kingPurchaseApply.getId()));
        if (!CollectionUtils.isEmpty(kingPurchaseApply.getMaterialLists())){
            saveMaterialAndDetail(kingPurchaseApply);
        }
        boolean updated = this.updateById(kingPurchaseApply);
        if ( !updated ) {
            return AjaxResult.error( "修改采购申请单失败！!" );
        }
        return AjaxResult.success ( "修改采购申请单成功!",kingPurchaseApply.getId());
    }

    /**
     * 保存采购申请单物料明细
     * @param kingPurchaseApply
     */
    private void saveMaterialAndDetail(KingPurchaseApplyEntity kingPurchaseApply){
        List<KingPurchaseApplyMaterialEntity> materialLists = kingPurchaseApply.getMaterialLists();
        materialLists.stream().filter(Objects::nonNull).forEach(purchaseApplyMaterial -> {
            purchaseApplyMaterial.setId(SnowflakeIdWorker.getInstance().nextStringId());
            purchaseApplyMaterial.setPurchaseApplyId(kingPurchaseApply.getId());
            purchaseApplyMaterial.setUserId(kingPurchaseApply.getCreateName());
            purchaseApplyMaterial.setCreateTime(DateUtils.getNowDate());
            boolean save = purchaseApplyMaterialService.save(purchaseApplyMaterial);
            if(!save){
                throw new RuntimeException("新增采购申请单物料明细失败！");
            }
        });
    }

    /**
     * 查询金蝶-采购申请单
     *
     * @param id 金蝶-采购申请单ID
     * @return 金蝶-采购申请单
     */
    @Override
    public KingPurchaseApplyEntity selectKingPurchaseApplyEntityById(String id)
    {
        KingPurchaseApplyEntity kingPurchaseApply = kingPurchaseApplyMapper.selectKingPurchaseApplyEntityById(id);
        if(Objects.nonNull(kingPurchaseApply)){
            List<KingPurchaseApplyMaterialEntity> materialList = purchaseApplyMaterialService.list(new LambdaQueryWrapper<KingPurchaseApplyMaterialEntity>().eq(KingPurchaseApplyMaterialEntity::getPurchaseApplyId, kingPurchaseApply.getId()));
            kingPurchaseApply.setMaterialLists(materialList);
        }
        return kingPurchaseApply;
    }

    /**
     * 查询金蝶-采购申请单列表
     *
     * @param kingPurchaseApplyEntity 金蝶-采购申请单
     * @return 金蝶-采购申请单
     */
    @Override
    public List<KingPurchaseApplyEntity> selectKingPurchaseApplyEntityList(KingPurchaseApplyEntity kingPurchaseApplyEntity)
    {
        return kingPurchaseApplyMapper.selectKingPurchaseApplyEntityList(kingPurchaseApplyEntity);
    }

    /**
     * 新增金蝶-采购申请单
     *
     * @param kingPurchaseApplyEntity 金蝶-采购申请单
     * @return 结果
     */
    @Override
    public int insertKingPurchaseApplyEntity(KingPurchaseApplyEntity kingPurchaseApplyEntity)
    {
        kingPurchaseApplyEntity.setCreateTime(DateUtils.getNowDate());
        return kingPurchaseApplyMapper.insertKingPurchaseApplyEntity(kingPurchaseApplyEntity);
    }

    /**
     * 修改金蝶-采购申请单
     *
     * @param kingPurchaseApplyEntity 金蝶-采购申请单
     * @return 结果
     */
    @Override
    public int updateKingPurchaseApplyEntity(KingPurchaseApplyEntity kingPurchaseApplyEntity)
    {
        kingPurchaseApplyEntity.setUpdateTime(DateUtils.getNowDate());
        return kingPurchaseApplyMapper.updateKingPurchaseApplyEntity(kingPurchaseApplyEntity);
    }

    /**
     * 批量删除金蝶-采购申请单
     *
     * @param ids 需要删除的金蝶-采购申请单ID
     * @return 结果
     */
    @Override
    public int deleteKingPurchaseApplyEntityByIds(String[] ids)
    {
        for(String id : ids){
            purchaseApplyMaterialService.remove(new LambdaQueryWrapper<KingPurchaseApplyMaterialEntity>().eq(KingPurchaseApplyMaterialEntity::getPurchaseApplyId,id));
        }
        return kingPurchaseApplyMapper.deleteKingPurchaseApplyEntityByIds(ids);
    }

    /**
     * 删除金蝶-采购申请单信息
     *
     * @param id 金蝶-采购申请单ID
     * @return 结果
     */
    @Override
    public int deleteKingPurchaseApplyEntityById(String id)
    {
        purchaseApplyMaterialService.remove(new LambdaQueryWrapper<KingPurchaseApplyMaterialEntity>().eq(KingPurchaseApplyMaterialEntity::getPurchaseApplyId,id));
        return kingPurchaseApplyMapper.deleteKingPurchaseApplyEntityById(id);
    }
}
